package cn.sangedon.review.data.spider.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import cn.sangedon.review.common.domain.data.SnowballQuotation;
import cn.sangedon.review.common.domain.data.SpiderMateData;
import cn.sangedon.review.common.service.data.SnowballQuotationService;
import cn.sangedon.review.common.service.data.TradingDateService;
import cn.sangedon.review.data.constant.SpiderEnum;
import cn.sangedon.review.data.spider.AbstractStockInfoSpider;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * 从雪球获取实时行情交易数据
 */
@Slf4j
@Component
public class SnowballQuotationSpider extends AbstractStockInfoSpider {
    @Autowired
    private SnowballQuotationService snowballQuotationService;

    @DubboReference
    private TradingDateService tradingDateService;

    @Override
    public void runJob(List<SpiderMateData> spiderMateDataList) {
        spiderMateDataList.stream().filter(e -> e.getSpiderName().equals(SpiderEnum.SNOWBALL_QUOTATION_INTIME.getName())).findFirst()
                          .ifPresent(e -> {
                              addSchedule(e);
                          });
    }

    @Override
    public void crawlData() {
        if (!tradingDateService.isTradingHours(null)) {
            log.info("当前时间非交易时间, 无需重复获取实时行情数据");
            return;
        }

        AtomicInteger index = new AtomicInteger(0);
        while (index.getAndIncrement() < 3 && !processData()) {
            log.info("重试{}次获取雪球实时行情数据", index.get());
        }
    }

    private boolean processData() {
        try {
            log.info("开始获取雪球行情数据");
            String spiderUrl = String.format(super.getSpiderMateData().getSpiderUrl(), 10, System.currentTimeMillis());

            String body = HttpUtil.get(spiderUrl);
            JSONObject retObj = JSONObject.parseObject(body);
            if (!retObj.getInteger("error_code").equals(0)) {
                log.info("获取雪球行情数据失败:{}", body);
                return false;
            }
            JSONObject data = retObj.getJSONObject("data");
            Integer count = data.getInteger("count");

            String url = String.format(super.getSpiderMateData().getSpiderUrl(), count, System.currentTimeMillis());
            String resBody = HttpUtil.get(url);
            JSONObject resObj = JSONObject.parseObject(resBody);
            if (!resObj.getInteger("error_code").equals(0)) {
                log.info("获取雪球行情数据失败:{}", resBody);
                return false;
            }
            JSONArray dataList = resObj.getJSONObject("data").getJSONArray("list");
            List<SnowballQuotation> stockQuotations = new ArrayList<>();
            String now = DateUtil.now();
            dataList.forEach(json -> {
                JSONObject obj = (JSONObject) json;
                SnowballQuotation dayInfo = new SnowballQuotation();
                dayInfo.setCode(obj.getString("symbol").substring(2));
                dayInfo.setName(obj.getString("name"));
                dayInfo.setTradingDate(now);
                String percent = obj.getString("percent");
                if (StringUtils.isEmpty(percent)) {
                    dayInfo.setChangeRate(new BigDecimal(0));
                } else {
                    dayInfo.setChangeRate(new BigDecimal(percent));
                }

                dayInfo.setChangeAmount(obj.getBigDecimal("chg"));
                dayInfo.setTradingVolume(
                    new BigDecimal(obj.getInteger("volume") == null ? 0 : obj.getInteger("volume")).divide(new BigDecimal(100)));
                dayInfo.setTradingAmount(
                    new BigDecimal(obj.getInteger("amount") == null ? 0 : obj.getInteger("amount")).divide(new BigDecimal(10000)));
                dayInfo.setAmplitudeRate(obj.getBigDecimal("amplitude"));
                dayInfo.setTurnoverRate(obj.getBigDecimal("turnover_rate"));
                dayInfo.setClosingPrice(obj.getBigDecimal("current"));
                dayInfo.setGmtCreate(now);
                dayInfo.setGmtModified(now);
                stockQuotations.add(dayInfo);
            });
            snowballQuotationService.saveBatch(stockQuotations);
            log.info("获取雪球行情数据成功：{}", dataList.size());
            return true;
        } catch (Exception e) {
            log.error("获取雪球行情数据失败:{}", DateUtil.today(), e);
            return false;
        }
    }
}
